package com.gwt.dispatcher.dispatcher.server;

import java.util.HashMap;
import java.util.Map;

import com.gwt.dispatcher.dispatcher.shared.Action;
import com.gwt.dispatcher.dispatcher.shared.Result;

/**
 * <p>
 * Provides a completely Type-Safe Map for Action Handlers
 * </p>
 * 
 * <ul>
 * 	<li>the <b>key</b> of this "map" is the <b>Class of the action</b> and
 *  <li>the <b>value</b> it's an instance of the <b>ActionHandler</b> class
 * </ul>
 * 
 * @author cristian.n.miranda
 *
 */
public class HandlerManagerMap {
	
	@SuppressWarnings("unchecked")
	private static final Map map = new HashMap();
	
	/**
	 * 
	 * @param <T>	Type of the the Class that implements Result
	 * 				(typically a Value Object to be transferred between server and client)
	 * @param <A>   The type of the Action which would return the type <b>&lt;T&gt;</b>
	 * @param <H>	The type of the Handler that Serves that particular Action <b>&lt;A&gt;</b>
	 * 
	 * @param clazz 	Class of the incoming Action (from Client  to Server) (ie: <code>GetSwitchInfo.class</code>)
	 * @param handler 	Instance of the Handler that will server that particular Action (ie: <code>new GetSwitchInfoHandler()</code>) 
	 */
	@SuppressWarnings("unchecked")
	public <T extends Result, A extends Action<T>, H extends ActionHandler<A,T>> void register(Class<A> clazz, H handler) {
		map.put(clazz, handler);
	}
	
	@SuppressWarnings("unchecked")
	public <T extends Result, A extends Action<T>, H extends ActionHandler<A,T>> H get(Class<A> clazz) {
		
		if ( map.containsKey( clazz ) ) {
			return (H) map.get( clazz );
		}
		
		return null;
	}
	
	@SuppressWarnings("unchecked")
	public <T extends Result> ActionHandler<Action<T>, T> getHandler(Action<T> action) {
		Class<Action<T>> actionClass = (Class<Action<T>>) action.getClass();
		ActionHandler<Action<T>, T> handler = this.get(actionClass);
		return handler;
	}

}
